package com.netty.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.netty.admin.mapper.*;
import com.netty.admin.service.FriendService;
import com.netty.admin.service.GroupService;
import com.netty.common.entity.Friend;
import com.netty.common.entity.Group;
import com.netty.common.entity.GroupRelation;
import com.netty.common.entity.User;
import com.netty.common.entity.bo.GroupFormBo;
import com.netty.common.entity.bo.GroupMemberFormBo;
import com.netty.common.entity.result.Result;
import com.netty.common.entity.vo.GroupVo;
import com.netty.common.enums.ExceptionEnum;
import com.netty.common.util.security.SecurityUtils;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import org.springframework.amqp.rabbit.connection.RabbitResourceHolder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import sun.java2d.loops.GeneralRenderer;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author LiuXiaoYu
 * @date 2022/2/1- 13:33
 */
@Service
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements GroupService {

    @Autowired
    private GroupMapper groupMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private GroupRelationMapper groupRelationMapper;


    /**
     * 创建群
     * @param groupFormBo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<?> addGroup(GroupFormBo groupFormBo) {
        Group group = new Group();
        BeanUtils.copyProperties(groupFormBo,group);
        int insert = groupMapper.insert(group);
        if (insert>0){
            //说明创建群组成功 还要将创建人加入群组
            GroupRelation groupRelation = new GroupRelation();
            groupRelation.setGroupId(group.getGroupId());
            String username = SecurityUtils.getUsername();
            User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
            if (Objects.isNull(user)){
                return Result.error(ExceptionEnum.NEED_LOGIN,"请先登录");
            }
            groupRelation.setMemberId(user.getUserId());
            int insert1 = groupRelationMapper.insert(groupRelation);
            if (insert1>0){
                return Result.success("添加群组成功");
            }
        }
        return Result.error(ExceptionEnum.ERROR,"添加群组失败");
    }

    /**
     * 获取该用户创建的所有群组
     * @return
     */
    @Override
    public Result<?> getAllGroups() {
        String username = SecurityUtils.getUsername();
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if (Objects.isNull(user)){
            return Result.error(ExceptionEnum.NEED_LOGIN,"请先登录");
        }
        //获取该用户下的所有群组 group是mysql的关键字 这里报错就用xml
       // List<Group> groups = groupMapper.selectList(new LambdaQueryWrapper<Group>().eq(Group::getAdmin, user.getUserId()));
        List<Group> groups=groupMapper.getUserAllGroups(user.getUserId());
        //获取群组中间表的所有数据 key->groupid(唯一) value->grouprelation
        Map<Integer, List<GroupRelation>> map = groupRelationMapper.selectList(null)
                .stream().collect(Collectors.groupingBy(GroupRelation::getGroupId));
        //用来存储最后返回的数据结果
        List<GroupVo> groupVos=new ArrayList<>();
        for (Group group:groups) {
            if (map.containsKey(group.getGroupId())) {
                List<GroupRelation> groupRelations = map.get(group.getGroupId());
                //获取该群下所有成员id集合
                List<Integer> memberIds = groupRelations.stream().map(GroupRelation::getMemberId).collect(Collectors.toList());
                GroupVo groupVo = new GroupVo()
                        .setGroupId(group.getGroupId()).setMembersId(memberIds)
                        .setAdmin(group.getAdmin()).setDescription(group.getDescription())
                        .setGroupName(group.getGroupName()).setImage(group.getImage());
                groupVos.add(groupVo);
            }
        }
        //返回数据
        return Result.success(groupVos);
    }

    /**
     * 获取该用户加入的所有群组
     * @return
     */
    @Override
    public Result<?> getAlreadyJoinedGroups() {
        //获取
        String username = SecurityUtils.getUsername();
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if (Objects.isNull(user)){
            return Result.error(ExceptionEnum.NEED_LOGIN,"请先登录");
        }
        //从中间表获取该用户加入的所有群组
       //****mysql 5.7 groupby 抛异常 sql_mode=only_full_group_by
        //解决修改mysql参数:SET GLOBAL sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
        //SET SESSION sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';


        //从中间表获取该用户加入的所有群组
        List<GroupRelation> groupRelationList = groupRelationMapper.selectList(new LambdaQueryWrapper<GroupRelation>().eq(GroupRelation::getMemberId,user.getUserId()).groupBy(GroupRelation::getGroupId));
        List<Integer> groupIds = groupRelationList.stream().map(GroupRelation::getGroupId).collect(Collectors.toList());
        List<Group> groups = groupMapper.getAllGroups(groupIds);
        //获取群组中间表的所有数据 key->groupid(唯一) value->grouprelation
        Map<Integer, List<GroupRelation>> map = groupRelationMapper.selectList(null)
                .stream().collect(Collectors.groupingBy(GroupRelation::getGroupId));
        //用来存储最后返回的数据结果
        List<GroupVo> groupVos=new ArrayList<>();
        for (Group group:groups) {
            if (map.containsKey(group.getGroupId())) {
                List<GroupRelation> groupRelations = map.get(group.getGroupId());
                //获取该群下所有成员id集合
                List<Integer> memberIds = groupRelations.stream().map(GroupRelation::getMemberId).collect(Collectors.toList());
                GroupVo groupVo = new GroupVo()
                        .setGroupId(group.getGroupId()).setMembersId(memberIds)
                        .setAdmin(group.getAdmin()).setDescription(group.getDescription())
                        .setGroupName(group.getGroupName()).setImage(group.getImage());
                groupVos.add(groupVo);
            }
        }

        return Result.success(groupVos);
    }

    /**
     * 给一个群添加群成员
     * @param groupMemberFormBo
     * @return
     */
    @Override
    public Result<?> addMember(GroupMemberFormBo groupMemberFormBo) {
        GroupRelation groupRelation = new GroupRelation();
        BeanUtils.copyProperties(groupMemberFormBo,groupRelation);
        Integer groupId = groupRelation.getGroupId();
        //GROUP msyql关键字要写xml
        Group group = groupMapper.getGroupById(groupId);
        if (group==null){
            return Result.error(ExceptionEnum.ERROR,"加入的群组不存在");
        }
        Integer memberId = groupRelation.getMemberId();
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUserId, memberId));
        if (user==null){
            return Result.error(ExceptionEnum.ERROR,"添加的成员不存在");
        }
        int insert = groupRelationMapper.insert(groupRelation);
        if (insert>0){
            return Result.success();
        }
        return Result.error(ExceptionEnum.ERROR,"添加群成员失败");
    }
}
